/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
*/
package com.jorritdevries.console.elements
{
	import com.jorritdevries.console.ResizeEvent;
	import com.jorritdevries.console.UIController;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Mouse;
	import flash.utils.getDefinitionByName;

	public class ResizeArea extends MovieClip
	{
		private var mMinimized:Boolean;
		private var mResizeVertical:Boolean;
		private var mResizeHorizontal:Boolean;
		private var mCursor:Cursor;
		private var mCursorPos:Point;
		
		// References to clips. A set of clips is used for shwoing the proper
		// cursor when needed
		private var mTL:Sprite;
		private var mT:Sprite;
		private var mTR:Sprite;
		private var mL:Sprite;
		private var mR:Sprite;
		private var mBL:Sprite;
		private var mB:Sprite;
		private var mBR:Sprite;
		
		public function ResizeArea()
		{
			mMinimized = mResizeVertical = mResizeHorizontal = false;
			mCursorPos = new Point();
			
			var TL:Class = getDefinitionByName("com.jorritdevries.console.elements.TL") as Class;
			var TB:Class = getDefinitionByName("com.jorritdevries.console.elements.TB") as Class;
			var TR:Class = getDefinitionByName("com.jorritdevries.console.elements.TR") as Class;
			var L:Class = getDefinitionByName("com.jorritdevries.console.elements.L") as Class;
			var R:Class = getDefinitionByName("com.jorritdevries.console.elements.R") as Class;
			var BL:Class = getDefinitionByName("com.jorritdevries.console.elements.BL") as Class;
			var BR:Class = getDefinitionByName("com.jorritdevries.console.elements.BR") as Class;
			
			mTL = Sprite(new TL());
			mT = Sprite(new TB());
			mTR = Sprite(new TR());
			mL = Sprite(new L());
			mR = Sprite(new R());
			mBL = Sprite(new BL());
			mB = Sprite(new TB());
			mBR = Sprite(new BR());
			mT.x = mL.y = mR.y = mB.x = 16;
			mT.y = -5;
			mTR.x = mR.x = mBL.y = mB.y = mBR.x = mBR.y = 42;
			mTL.alpha = mT.alpha = mTR.alpha = mL.alpha = mR.alpha = mBL.alpha = mB.alpha = mBR.alpha = 0;
			
			addChild(mTL);
			addChild(mT);
			addChild(mTR);
			addChild(mL);
			addChild(mR);
			addChild(mBL);
			addChild(mB);
			addChild(mBR);
			
			// Set mouse handlers for cursor
			mTL.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mT.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mTR.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mL.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mR.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mBL.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mB.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			mBR.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			
			mTL.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mT.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mTR.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mL.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mR.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mBL.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mB.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			mBR.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
			
			mTL.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mT.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mTR.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mL.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mR.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mBL.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mB.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			mBR.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			
			mTL.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mT.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mTR.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mL.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mR.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mBL.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mB.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mBR.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			
			mCursor = Cursor.getInstance();
			
			setSize(width, height);
		}
		
		public function minimize():void
		{
			mMinimized = true;
			
			// Reposition L and R
			mL.y = mR.y = 0;
			
			// Hide everything except sides
			mT.visible = mB.visible = mTL.visible = mTR.visible = mBL.visible = mBR.visible = false;
			
			setSize(width, height);
		}
		
		public function maximize():void
		{
			mMinimized = false;
			
			// Reposition L and R
			mL.y = mR.y = UIController.RESIZE_CORNER_SIZE;
			
			// Show all
			mT.visible = mB.visible = mTL.visible = mTR.visible = mBL.visible = mBR.visible = true;
			
			setSize(width - (2 * UIController.RESIZE_BORDER_SIZE),
				height - UIController.RESIZE_CORNER_SIZE - UIController.RESIZE_BORDER_SIZE);
		}
		
		public function setSize(width:Number, height:Number):void
		{
			if (!mMinimized)
			{
				// Top
				mT.width = width - (2 * UIController.RESIZE_CORNER_SIZE);
				// Bottom
				mB.width = width - (2 * UIController.RESIZE_CORNER_SIZE);
				mB.y = height;
				// Left
				mL.height = height - (2 * UIController.RESIZE_CORNER_SIZE);
				// Right
				mR.height = height - (2 * UIController.RESIZE_CORNER_SIZE);
				mR.x = width;
				// Corners
				mTR.x = width;
				mBL.y = height;
				mBR.x = width;
				mBR.y = height;
			}
			else
			{
				// Only update vertical parts
				mL.height = height;
				mR.height = height;
				mR.x = width;
			}
		}
		
		private function mouseOverHandler(e:MouseEvent):void
		{
			switch (e.target)
			{
			case mTL:
			case mBR:
				mCursor.useBitmap(Cursor.TOP_TO_BOTTOM);
				break;
			case mT:
			case mB:
				mCursor.useBitmap(Cursor.VERTICAL);
				break;
			case mTR:
			case mBL:
				mCursor.useBitmap(Cursor.BOTTOM_TO_TOP);
				break;
			case mL:
			case mR:
				mCursor.useBitmap(Cursor.HORIZONTAL);
				break;
			}
			
			Mouse.hide();
			Sprite(e.target).addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
		}
		
		private function mouseOutHandler(e:MouseEvent):void
		{
			Mouse.show();
			Sprite(e.target).removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			mCursor.hide();
		}
		
		private function mouseMoveHandler(e:MouseEvent):void
		{
			mCursor.x = e.localX * e.target.scaleX + e.target.x;
			mCursor.y = e.localY * e.target.scaleY + e.target.y;
			e.updateAfterEvent();
			mCursor.show();
			
			if (mResizeVertical || mResizeHorizontal)
			{
				// TODO use startDrag to do this resizing
				// Calculate difference in movement
				var movX:Number = mCursor.x - mCursorPos.x;
				var movY:Number = mCursor.y - mCursorPos.y;
			
				mCursorPos.x = mCursor.x;
				mCursorPos.y = mCursor.y;
				
				var hSize:Number = width - (2 * UIController.RESIZE_BORDER_SIZE) + (mResizeHorizontal ? movX : 0);
				var vSize:Number = height - (2 * UIController.RESIZE_BORDER_SIZE) + (mResizeVertical ? movY : 0);
				
				var evt:ResizeEvent = new ResizeEvent(ResizeEvent.RESIZE, hSize, vSize);
				dispatchEvent(evt);
			}
		}
		
		private function mouseDownHandler(e:MouseEvent):void
		{
			mCursorPos.x = e.localX * e.target.scaleX + e.target.x;
			mCursorPos.y = e.localY * e.target.scaleY + e.target.y;
			
			switch (e.target)
			{
			case mTL:
			case mBR:
			case mTR:
			case mBL:
				mResizeVertical = mResizeHorizontal = true;
				break;
			case mT:
			case mB:
				mResizeVertical = true;
				break;
			case mL:
			case mR:
				mResizeHorizontal = true;
				break;
			}
			
			// Listen to on release outside events
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		}
		
		private function mouseUpHandler(e:MouseEvent):void
		{
			// Remove release outside events
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			mResizeVertical = mResizeHorizontal = false;
		}
	}
	
}